package main

import (
	"fmt"
	"math"

	"github.com/duke-git/lancet/v2/slice"
	"github.com/samber/lo"
)

var (
	//从2015年开始
	datasource = map[string] /*代码*/ []float64 /*年收益*/ {
		//红利ETF
		"510880": {12.34, -4.74, 20.49, -13.92, 16.52, -0.61, 10.73, 2.56, 7.49, 15.01},
		//标普500
		"513500": {7.61, 27.81, 3.52, -3.52, 34.01, 8.55, 25.63, -13.51, 27.73, 24.33},

		//上证50
		"510050": {-4.78, -2.87, 23.76, -16.06, 29.97, 17.65, -8.06, -14.84, -7.79, 4.40},
		//黄金ETF
		"518880": {-7.46, 18.10, 2.73, 4.36, 19.75, 13.77, -5.38, 9.42, 16.61, 15.77},
		//城投债ETF
		"511220": {12.34, 4.79, 0.68, 7.65, 4.82, 2.61, 5.54, 2.65, 5.95, 2.83},
	}
)

func main() {
	eval([]string{"510880", "513500", "518880", "511220"}, []float64{0.1, 0.1, 0.40, 0.40}, 0.0)
	eval2([]string{"510050", "518880", "511220"}, []float64{0.25, 0.25, 0.5})
}

// eval 年底再平衡； 仓位固定
func eval(codes []string, parts []float64, offest float64) {
	//设定初始资金100万
	var totalMoney = 1_000_000.0

	//初始市值

	var shizhiList = map[string]float64{}
	for i, code := range codes {
		shizhiList[code] = totalMoney * parts[i]
	}

	// 每年年底再平衡

	everyYearList := []float64{} //每年收益

	for year := 2015; year <= 2024; year++ { //loop year
		for _, code := range codes {
			shizhiList[code] *= 1.0 + datasource[code][year-2015]/100.0
		}

		//当年收益率
		var sum float64
		for _, money := range shizhiList {
			sum += money
		}
		shouyi := (sum - totalMoney) / totalMoney * 100.0
		totalMoney = sum
		everyYearList = append(everyYearList, shouyi)

		//再平衡
		for i, code := range codes {
			if math.Abs(shizhiList[code]/sum-parts[i]) >= offest {
				shizhiList[code] = totalMoney * parts[i]
			}
		}
	}

	fmt.Printf("总收益率：%.2f,平均年化=%.2f,最高年收益=%.2f,最低年收益=%.2f\n",
		lo.Sum(everyYearList), lo.Mean(everyYearList), lo.Max(everyYearList), lo.Min(everyYearList))
}

// eval2 年底再平衡； 仓位动态变化
func eval2(codes []string, partions []float64) {
	//设定初始资金100万
	var totalMoney = 1_000_000.0

	//初始化仓位比例
	var parts = make(map[string]float64, len(codes))
	for i, code := range codes {
		parts[code] = partions[i]
	}

	//初始市值
	var shizhiList = map[string]float64{}
	for _, code := range codes {
		shizhiList[code] = totalMoney * parts[code]
	}

	// 每年年底再平衡

	everyYearList := []float64{} //每年收益

	for year := 2015; year <= 2024; year++ { //loop year
		for _, code := range codes {
			shizhiList[code] *= 1.0 + datasource[code][year-2015]/100.0
		}

		//当年收益率
		var sum float64
		for _, money := range shizhiList {
			sum += money
		}
		shouyi := (sum - totalMoney) / totalMoney * 100.0
		totalMoney = sum
		everyYearList = append(everyYearList, shouyi)

		//
		//再平衡
		//

		//按当年收益排序  升序
		slice.SortBy(codes, func(a, b string) bool {
			return datasource[a][year-2015] < datasource[b][year-2015]
		})

		//收益过低或过低时，最高收益的品种仓位移至最低收益的品种
		var (
			diff  float64
			worst = datasource[codes[0]][year-2015] / 100.0
			best  = datasource[codes[len(codes)-1]][year-2015] / 100.0
		)
		if worst <= -0.2 || best >= 0.2 {
			diff = parts[codes[len(codes)-1]]
		} else if worst <= -0.15 || best >= 0.15 {
			diff = parts[codes[len(codes)-1]] * 0.75
		} else if worst <= -0.1 || best >= 0.1 {
			diff = parts[codes[len(codes)-1]] * 0.5
		}
		parts[codes[len(codes)-1]] -= diff
		parts[codes[0]] += diff

		for _, code := range codes {
			shizhiList[code] = totalMoney * parts[code]
		}

		//fmt.Printf("%d 仓位： %v\n", year, parts)
	}

	fmt.Printf("总收益率：%.2f,平均年化=%.2f,最高年收益=%.2f,最低年收益=%.2f\n",
		lo.Sum(everyYearList), lo.Mean(everyYearList), lo.Max(everyYearList), lo.Min(everyYearList))
}
